package main

import (
	"context"
	"fmt"
	"time"
)

func run(ctx context.Context) {
	select { // 执行任意一个非阻塞的字句
	case <-time.After(10 * time.Second):
		fmt.Println("timeout")
	case <-ctx.Done(): // 过了deadline时间则自动触发解除阻塞
		fmt.Println("error: ", ctx.Err())
	}
}

func main() {
	fmt.Println(1111)
	d := time.Now().Add(5 * time.Second) //改为大于10和小于10的值，结果会不一样
	//这里不会阻塞
	ctx, cancel := context.WithDeadline(context.Background(), d) //WithDeadline是到了截止时刻取消，WithTimeout是过了一段时间取消
	fmt.Println(22222)
	defer func() {
		fmt.Println(333)
		cancel()
	}()

	run(ctx)

}

// 用法总结:
// 1. context.WithDeadline()方法执行后不会阻塞代码
// 2. 如果达到context设置的超时时间，context.Done()方法会解除阻塞
// 3. 如果手动执行cancel()方法，则context.Done()方法也会解除阻塞
